package com.netty.http.snoop;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;

/**
 * An HTTP server that sends back the content of the received HTTP request in a
 * pretty plaintext form.
 */
public final class HttpSnoopServer {

	static final boolean SSL = System.getProperty("ssl") != null;
	static final int PORT = Integer.parseInt(System.getProperty("port", SSL ? "8443" : "8080"));

	private Thread thread;

	public void start() {
		thread = new Thread() {
			@Override
			public void run() {
				// Configure SSL.
				final SslContext sslCtx;
				// Configure the server.
				EventLoopGroup bossGroup = new NioEventLoopGroup(1);
				EventLoopGroup workerGroup = new NioEventLoopGroup();
				try {
					if (SSL) {
						SelfSignedCertificate ssc = new SelfSignedCertificate();
						sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
					} else {
						sslCtx = null;
					}

					ServerBootstrap b = new ServerBootstrap();
					b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
							.handler(new LoggingHandler(LogLevel.INFO))
							.childHandler(new HttpSnoopServerInitializer(sslCtx));

					Channel ch = b.bind(PORT).sync().channel();

					System.err.println("Open your web browser and navigate to " + (SSL ? "https" : "http")
							+ "://127.0.0.1:" + PORT + '/');

					ch.closeFuture().sync();
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					bossGroup.shutdownGracefully();
					workerGroup.shutdownGracefully();
				}
			}
		};
		thread.start();
	}
}